public class EventWithTasksGridExtension {

    String StatusText;                 // Error message if saving the Tasks fails
    String StatusTextNM;               // Error message if saving the next meeting fails 
    List<Task> ContTasks;              // The list of open tasks for this contact
    Boolean InsertFlag;                // Are we inserting a new task?
    Boolean IsNextMeet;                // Has the next meeting been created yet?
    private final Event event;         // The current event
    private Id eventwhoid;             // The Id of the contact for this event **** PRESUMES CONTACTS ****
    private Event nextevent;           // The next event

    public Boolean getHasContact () {
        return this.eventwhoid != null;
    }

    public String getStatusTextNM () {
        return this.StatusTextNM;
    }
    
    public Event getNextEvent () {
        return this.nextevent;
    }
    
    public Boolean getIsNextMeet () {
        return this.IsNextMeet;
    }

    // Constuctor for extending the standard controller
    public EventWithTasksGridExtension(ApexPages.StandardController stdController){
        System.debug('>>>>>>>>>>>>>>>>>>>EventWithTasksGridExtension');
        
        this.event = (Event)stdController.getSubject();
        
        // *** OPTIONAL - HAVE A STATUS ON AN EVENT
        //this.event.status__c = 'Completed';
        
        // Get the whoid field
        // Note that only the fields that are displayed in the associated Visualforce markup are available for queryinggetSubject SObject on this SObject. All other fields, including fields from any related objects, must be queried using a SOQL expression.
        Event event2 = [Select e.WhoId, e.StartDateTime  From Event e where e.Id = :event.Id];
        this.eventwhoid = event2.WhoId;
        
        // When do we next see this contact?
        List<Event> events = [Select e.Type, e.Subject, e.Description, e.ActivityDateTime, e.DurationInMinutes, e.WhoId From Event e where e.WhoId = :eventwhoid and e.StartDateTime > :event2.StartDateTime ORDER BY StartDateTime LIMIT 1];
        IsNextMeet = (events.size() > 0);
        if (IsNextMeet ){
            this.nextevent = events[0];
        }
        
        StatusText = '';
        StatusTextNM = '';
        ContTasks = TaskList();
        InsertFlag = false;
    }

    // Fill list with Tasks
    public List<Task> TaskList(){
        List<Task> cl;
        try {
    
           // Only load if we have a contact       
           if (this.eventwhoid != null){
               cl = [  SELECT t.WhoId, t.Subject, t.Status, t.Priority
                        , t.ActivityDate, t.Result__c, t.Type, t.OwnerId
                       FROM Task t 
                       WHERE t.WhoId = :eventwhoid
                       ];
           }
           
        } catch (QueryException e){
            system.debug(e.getMessage());
            StatusText = e.getMessage();
        }
        return cl;
    }

    // Called from Grid to get List of Tasks
    public List<Task> getContTasks () {
        if (InsertFlag){
           ContTasks.add(new Task(WhoId= this.eventwhoid, Status='Not Started', Priority='2 - Medium'));
           InsertFlag = false;
        }
        return ContTasks;
    }

    // Called from Page to pass values from grid to controller
    public void setContTasks(List<Task> ct) {
        ContTasks = ct;
    }

    // Called from Page to get StatusText
    public String getStatusText() {
        return StatusText;
    }
    
    // Called from "Save" Button
    public PageReference saveTasks () {
        try {
    
            // Only Save Tasks If We Have a Contact        
            if (this.eventwhoid != null)
                upsert ContTasks;
            
            // DKL changed to also save the event in the same save...
            update event;
            
        } catch (DMLException e) {
            system.debug(e.getMessage());
            StatusText = e.getMessage();
        }   
        ContTasks = TaskList();
        return null;
    }

    // Called from "Add" Button
    public PageReference addTask () {
        InsertFlag = true;
        return null;
    }
    
    // DKL 
    // Called from "Cancel" Button
    public PageReference cancelTasks() {
        // NOT SURE WHAT TO DO HERE... NEED TO DISCARD NEW RECORDS AND REVERT LIST
        return null;
    }
    
    // CREATE THE NEXT EVENT
    public PageReference saveNextMeet () {
        try {
            if(IsNextMeet) // only save if we have something
                upsert nextevent;
            
        } catch (DMLException e) {
            system.debug(e.getMessage());
            this.StatusTextNM = e.getMessage();
        }   
        return null;
    }
    
    // CREATE THE NEXT EVENT
    public PageReference newNextMeet () {
        if (!IsNextMeet){ 
        
            //*TODO* CALC THE NEXT MEETING DATE   
            
            
            this.nextevent = new Event(WhoId= this.eventwhoid, Type='Meeting');
            IsNextMeet = True;
        }
        return null;
    }
}